#include "../include/MainHeader.h"
#include "../include/errorcodes.h"

/*Inserts nodes into linked list in sorted order*/

void insertIntoLinkedList(struct LinkedListNode **head, fd data) {

	struct LinkedListNode *temp, *node;

	node = (struct LinkedListNode *) malloc (sizeof(struct LinkedListNode));
	
	node->fileDesc = (fd *) malloc(sizeof(fd));

	strcpy(node->fileDesc->file_name,data.file_name);

	strcpy(node->fileDesc->path,data.path);
	node->fileDesc->fileType = data.fileType;
	node->next = NULL;
	
	temp = *head;

	//1st entry
	if(temp->next == NULL)	{
		temp->next = node;
	}
	//if 1st node is alphabetically greater than the node to be inserted
	else if(strcmp(temp->next->fileDesc->file_name, data.file_name) > 0) {
		node->next = temp->next;
		temp->next = node;
	}
	else {
		while(strcmp(temp->next->fileDesc->file_name, data.file_name) < 0 && temp->next->next != NULL) {
			temp=temp->next;
		}
		if(temp->next->next == NULL && strcmp(temp->next->fileDesc->file_name, data.file_name) < 0) {
			temp->next->next = node;
		}
		else {
			node->next = temp->next;
			temp->next = node;
		}
	}

	/*for(temp = *head; temp != NULL; temp = temp->next) {
		printf("%s :\n", temp->fileDesc->file_name);
	}*/

}


int deleteFromLinkedList(struct LinkedListNode **head, fd data) {
	
	struct LinkedListNode *temp;

	temp = *head;
	if(temp->next == NULL)	{
		return 0;
	}
	else {
		//loop to goto to the location with the same name
		while(strcmp(temp->next->fileDesc->file_name, data.file_name) != 0 && temp->next->next != NULL) {
			temp=temp->next;
		}
		
		//check whether the entire file-descriptor matches, else move forward until the same name file exists
		while(strcmp(temp->next->fileDesc->file_name, data.file_name) == 0 && temp->next != NULL) {

			if((strcmp(temp->next->fileDesc->file_name, data.file_name) == 0)
			&& (strcmp(temp->next->fileDesc->path, data.path) == 0)
			&& (temp->next->fileDesc->fileType == data.fileType)) {

				temp->next = temp->next->next;
				//for(temp = *head; temp != NULL; temp = temp->next)
				//	printf("%s :", temp->fileDesc->file_name);
				return 1;
			}
			else {
				temp=temp->next;
			}
		}

		return 0;
	}
}

/*
struct LinkedListNode* searchLinkedList(struct LinkedListNode **head, fd data) {
	struct LinkedListNode *temp;
	struct LinkedListNode *searchedList, *t;

	int i = 0;

	temp = *head;
	searchedList = (struct LinkedListNode*) malloc (sizeof(struct LinkedListNode));
	
	if(temp->next == NULL)	{
		return 0;
	}
	else {
		while(strcmp(temp->next->fileDesc->file_name, data.file_name) != 0 && temp->next->next != NULL) {
			temp =temp->next;
		}
		
		if(strcmp(temp->next->fileDesc->file_name, data.file_name) == 0 ) {
			searchedList = temp->next;
			t = searchedList;
			 while(temp->next != NULL && strcmp(temp->next->fileDesc->file_name, data.file_name) == 0) {
				searchedList = temp->next;
				temp = temp->next;
				//printf("%s found in %s path\n", searchedList->fileDesc->file_name, searchedList->fileDesc->path);
				if(temp->next != NULL && strcmp(temp->next->fileDesc->file_name, data.file_name) == 0)
					searchedList = searchedList->next;
				else
					break;
			}
			searchedList->next = NULL;
			
			return t;
		}
		else {
			return NULL;
		}
		//return searchedList;
	}	
}
*/

void searchPrefixLinkedList(struct LinkedListNode **head, char* data,char* outputFile) {

	//printf("\nIn search prefix linked list\n");
	struct LinkedListNode *temp;
	struct LinkedListNode *tempList = NULL, *searchedList = NULL;
	char *tempData, *searchData;

	int len = 0;                        //keeps a track of length of the file/folder name
	int isPresent = 1;                  //keeps a track of whether the file/folder to be searched exists or not
	int mismatch=0;                     //keeps a track if a mismatch occurs between the file/folder name and the prefix string
	int countOfMatches = 0;             //keeps track of number of matches found

	FILE *fp = fopen(outputFile, "w");

	/*if(fp==NULL) {
		printf("searchfile_FAILURE %s \n", ERR_VFS_ADDFILE_08);
		return;
	}
	else {

		fclose(fp);
		fp = fopen(outputFile, "w");*/

		
		char a[10];
		temp = *head;
		//searchedList = (struct LinkedListNode*) malloc (sizeof(struct LinkedListNode));

		if(temp->next == NULL)	{
			//return 0;
		}
		else {
			while(temp->next != NULL  && isPresent==1) {
				tempData = temp->next->fileDesc->file_name;
				searchData = data;
				mismatch=0;
				len=0;
	
				//check whether the file/folder name matches the prefix string to be searched for
				while(len<strlen(data)) {
					//checks if the prefix string is alphabetically greater than the file/folder name, then the file doesn't exist at all 
					if((toascii(toupper(*tempData))-65) - (toascii(toupper(*searchData))-65) > 0) {
						isPresent = 0;
						mismatch = 1;
						tempList = NULL;
						break;
					}
					//if a match occurs, move to the next character
					else if(*tempData == *searchData ) {
						searchData++;
						tempData++;
					}
					//checks if any mismatch occurs between the file/folder name and the prefix string
					else{
						temp = temp->next;
						mismatch = 1;
						break;
					}
				
					len++;
				}
				//if any match occurs, update searchedList and move to the next node
				if(mismatch==0) {
					if(tempList==NULL) {
						tempList = temp->next;
						countOfMatches++;
						fputs("File/Folder : ",fp);
						fwrite(tempList->fileDesc->file_name, strlen(tempList->fileDesc->file_name), 1, fp);
						fputc('\n',fp);
						fputs("Path : ",fp);
						fwrite(tempList->fileDesc->path, strlen(tempList->fileDesc->path), 1, fp);
						fputc('\n',fp);
					}
					else {
						tempList = temp->next;
						countOfMatches++;
						fputs("File/Folder : ",fp);
						fwrite(tempList->fileDesc->file_name, strlen(tempList->fileDesc->file_name), 1, fp);
						fputc('\n',fp);
						fputs("Path : ",fp);
						fwrite(tempList->fileDesc->path, strlen(tempList->fileDesc->path), 1, fp);
						fputc('\n',fp);
					}
					temp = temp->next;
					tempList = tempList->next;
				}
			}
		}

		/*

		if(searchedList != NULL) {
			while(searchedList != NULL) {
				//fwrite(searchedList->, sizeof(char*), 1, fp);
				printf("3%s\n",searchedList->fileDesc->file_name);
				printf("3%s\n",searchedList->fileDesc->path);
				searchedList = searchedList->next;
			
			}
		}
		else
			printf("%s not found\n",data);*/
	fclose(fp);	
	//}

	printf("searchfile_SUCCESS %d \n", countOfMatches);
	
}




void updateFileDesc(struct LinkedListNode **head, fd data, char* newPath)
{

//printf("\nnew path in linkedlist= %s\n",newPath);
//printf("\nfilename in ll.c= %s\n",data.file_name);


	struct LinkedListNode *temp,*temp1;
	fd *searchedData;

	temp = *head;temp1=*head;

	if(temp->next == NULL)	{
		return;
	}
	else {


		while(strcmp(temp->next->fileDesc->file_name, data.file_name) != 0 && temp->next->next != NULL) {
			temp =temp->next;
		}

	

		//check whether the entire file-descriptor matches, else move forward until the same name file exists
		while(strcmp(temp->next->fileDesc->file_name, data.file_name) == 0 && temp->next != NULL) {
				

			if((strcmp(temp->next->fileDesc->file_name, data.file_name) == 0)
			&& (strcmp(temp->next->fileDesc->path, data.path) == 0)
			&& (temp->next->fileDesc->fileType == data.fileType)) {
								//printf("\n****pos3******\n");
				searchedData = temp->next->fileDesc;
				strcpy(searchedData->path, newPath);
			}
			else {
				temp = temp->next;
			}
		}

	}
	//printf("UPDATED LIST");
	while(temp1->next!=NULL) {
	///	printf("\nFilename : %s\n",temp1->next->fileDesc->file_name);
	//	printf("\nPath : %s\n",temp1->next->fileDesc->path);
		temp1 = temp1->next;
	}

}



